using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Web.Mvc;
using Wikey.Domain.Components;
using Wikey.Entity;
using Wikey.Domain.Repository;
using Wikey.Domain.Web;
using Wikey.Utilities.Extensions;

namespace Wikey.Web.Mvc.Controllers
{
    public class PageController : ControllerOn<IPageRepository>
    {
        public ActionResult Index()
        {

            ViewData.Model = Repository.SelectAll();
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post),ValidateInput(false)]
        [CompressFilter]
        public JsonResult Content(int? id) {
            
            var @page = Request.Params["Page"].Int();
            var @data = Request.Params["data"];

            var currentPage = Repository.Find(@page);
            var contentNodeRepository = Factory.Get<IContentNodeRepository>();
            var contentNode = new ContentNode {Id = 0, Text = @data};
            
            contentNodeRepository.Save(contentNode);
            
            var pageContentNode = new PageContentNode {ContentNode = contentNode, Page = currentPage};

            currentPage.PageContentNodes.Add(pageContentNode);
            
            Repository.Save( currentPage);

            var jsonResult =
                new JsonResult
                    {
                        Data = pageContentNode.ContentNode,
                        ContentType = typeof (ContentNode).FullName
                    };

            return jsonResult; 
        }
        public ActionResult Design()
        {
            return View();
        }
        public JsonResult Upload(int? id)
        {
            var files = HttpContext.Request.Files;
            var dictionary = new Dictionary<int, string>();
            var myPage = !id.HasValue ? null : Repository.Find(id.Value);

            for (var idx = 0; idx < files.Count; idx++)
            {
                var postedFile = files[idx];
                
                var documentRepository = Factory.Get<IDocumentRepository>();
                var document =
                    new Document
                        {
                            Filename = postedFile.FileName.UniqueFilename(),
                            Name = postedFile.FileName,
                            Page = !id.HasValue ? null : Repository.Find(id.Value),
                            Size = postedFile.ContentLength , 
                            ContentType = postedFile.ContentType
                        };

                postedFile.SaveAs(
                    String.Format("{0}/{1}",
                                  HttpContext.Server.MapPath("~/Uploads/")
                                  , document.Filename
                        )
                    );

                var dbId = 0;
                if(myPage == null )
                {
                    dbId = documentRepository.Save(document);    
                }
                else
                {
                    myPage.Documents.Add(document);
                    Repository.Save(myPage);
                }
                

                dictionary.Add(dbId , document.Name);
            }

            return GenerateJsonFilesString(dictionary);
        }

        private static JsonResult GenerateJsonFilesString(Dictionary<int, string> filesList)
        {
            var list = new List<UploadedFiles>();

            foreach (var pair in filesList)
            {
                list.Add(new UploadedFiles {Id = pair.Key, Filename = pair.Value});    
            }
            return new JsonResult { Data = list  , ContentType = typeof(UploadedFiles).FullName };
        }
      
        public JavaScriptResult Comment(FormCollection collection)
        {
            var pageId = collection["PageId"];
            var comment = collection["Comment"];
            var from = collection["From"];

            var pageIdInt = Convert.ToInt32(pageId);
            var myPage = Repository.Find(pageIdInt);
            var newComment =
                new Comment
                    {
                        Title = from,
                        Text = comment,
                        Created = DateTime.Now,
                        Identity = new Identity {SysUser = Authorization.CurrentUser}
                    };

            myPage.Comments.Add(newComment);

            Repository.Save(myPage);

            return new JavaScriptResult {Script = "Comment saved!"};
        }
        [CompressFilter]
        public ActionResult Look( string pageName )
        {
            Page page;

            if( pageName.Int() > 0 )
            {
                page = Repository.Find(pageName.Int());
            }
            else
            {
                page = Repository.Find(pageName);               
            }
            if (!String.IsNullOrEmpty( page.Tags))
            {
                page.TagList = Factory.Get<ITagRepository>().FindTagsOf(page.Tags.Split(','));
            }
            ViewData.Model = page;

            return View();
        }
       
        public ActionResult Create(string id)
        {
            //set to default, thus parameter will be passed to the View page.
            ViewData["SpaceId"] = 0;
            ViewData["HasSpace"] = false;
            ViewData["Parent"] = 0;

            var parentPage = id.Int();
            if( parentPage > 0 )
            {
                ViewData["Parent"] = parentPage;
            }
            else
            {
                try {
                    var parameters = id.TrimStart('{').TrimEnd('}').Split('@');

                    ViewData["SpaceId"] = parameters[0];
                    ViewData["SpaceName"] = parameters[1];
                    ViewData["HasSpace"] = true;
                } catch (Exception) {
                    ViewData["HasSpace"] = false;
                }
                
            }           

            return View();
        } 

        [AcceptVerbs(HttpVerbs.Post) , ValidateInput(false)]
        public JavaScriptResult Create(FormCollection collection)
        {
            try
            {
                var tags = collection["Tags"];
                var pageTags = new StringBuilder();

                if( !String.IsNullOrEmpty(tags))
                {
                    var possibleTags = tags.Split(',');
                    foreach (var tag in  possibleTags)
                        {
                            if( String.IsNullOrEmpty(tag.Trim()))
                                continue;
                            
                            var tagRepo = Factory.Get<ITagRepository>();
                            tagRepo.Save(tag);
                            pageTags.Append(tag.Trim()).Append(",");
                        }
                   
                }

                var contentNode = new ContentNode
                {
                    Id = 0,
                    Text = collection["data"],
                    Description = " New content from Page " , 
                    CreatedBy = Session["user"] as User
                };

                Factory.Get<IContentNodeRepository>().Save(contentNode);


                var spaceRepository = Factory.Get<ISpaceRepository>();
                
                var parentPageId = collection["Parent"].Int();

                var page = new Page {
                    Id = 0 , 
                    Name = collection["Name"], 
                    Space = spaceRepository.Find(collection["Space"].Int()),
                    CreatedBy = Session["user"] as User,
                    ModifiedBy= Session["user"] as User , 
                    CreatedAt = DateTime.Now ,
                    ModifiedAt = DateTime.Now,
                    Description = collection["Description"] ,
                    Parent = Repository.Find(parentPageId),
                    Tags = pageTags.ToString()
                };

                var relatedDocumentsString = collection["documents"];
                

                var pageContentNode = 
                    new PageContentNode {ContentNode = contentNode, Page = page};

                page.PageContentNodes.Add(pageContentNode);

                var ids = relatedDocumentsString.Split('|');
                var documentRepository = Factory.Get<IDocumentRepository>();
                foreach (var id in ids)
                {
                    var documentId = id.Int();
                    if (documentId == 0) continue;

                    var document = documentRepository.Find(documentId);
                    document.Page = page; 
                    page.Documents.Add(document);
                }

               var dbId =  Repository.Save(page);


                var result =
                    new JavaScriptResult
                        {
                            Script = String.Format("{{'Id':{0},'Message':'Thanks saved with'}}", dbId)
                        };
                return result; 
            }
            catch(Exception ex)
            {
                var result = new JavaScriptResult {Script = ex.Message};
                return result;
            }
        }
        [CompressFilter]
        public FileStreamResult Export( string id )
        {

            var stream = new MemoryStream();

            var exportPath = HttpContext.Server.MapPath(
                   String.Format("~/Export{0}.pdf" , Guid.NewGuid().ToString("n")));

            var exportInstance = new PdfExport();
            exportInstance.Generate(exportPath,"content");
            
            var result = new FileStreamResult( new FileStream(exportPath,FileMode.Open), "application/pdf");
            result.FileDownloadName = "Export.pdf";
            
            return result;
        }
        public ActionResult Edit(int id)
        {
            
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(int id, FormCollection collection)
        {
            try
            {
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }
    }

    public class UploadedFiles {
        public int Id { get; set; }
        public string Filename { get; set; }
    }
}
